'''
【基础函数·六爻排盘】
- handle_coinNum
处理输入的字符串 --> 主卦 变卦 硬币数列表 发动列表，
- other function
其他都是辅助函数

卦象的处理细节比较杂碎
写成函数，存放在这个文件中
调用这个文件的函数
可以让代码变得简洁
'''
# from constants import _getGuaIdx, _getCoinNumLst
from mapping.numLst2idx import GuaConverter
from mapping.idx2numLst import _get_num_lst_from_pair

# 检查 012021，转换为 主卦list/变卦list，找到 gua/biangua
# 特征：len()==6 and .isdigit()


# 检查 25 26，转换为  主卦list/变卦list，找到 012021
# 特征：len()<6

# 分割函数
# 强制把所有的分割符，转化为/

'''raw string -> list'''


def split_n_replace(string: str):
    # if '.' in string:
    # reverse = True
    delimainder = ' .,-，。'
    for deli in delimainder:
        string = string.replace(deli, '/')
    return [int(c) for c in string.split('/') if c.isdigit()]


def isFormatLen6Max3(string: str):
    return len(string) == 6 and all(0 <= int(c) <= 3 for c in string)


def isFormatLen2Max64(lst: list[int]):
    return len(lst) in [1, 2] and all(0 <= int(c) <= 64 for c in lst)


'''parameter process'''


def handle_coinNum(string: str):
    if isinstance(string, int):
        string = str(string)
    elif isinstance(string, str):
        string = string.strip()
    else:
        raise ValueError(f'您的输入: {string},{type(string)}, 硬币数组应该是一串数字!')

    # format_1:120321
    if isFormatLen6Max3(string):
        coinNumLst = [int(c) for c in string][::-1]  # 返回词典，含有主卦变卦序数，coinNum
        triggerLst, gua, biangua = _toGuaNum(coinNumLst)
    else:
        split_lst = split_n_replace(string)
        # format_1.1:1 2 0 3 2 1 or 1.2.0.3.2.1
        if isFormatLen6Max3(split_lst):
            coinNumLst = split_lst  # 返回词典，含有主卦变卦序数，coinNum
            triggerLst, gua, biangua = _toGuaNum(coinNumLst)

        # format_2:5 31 or 62
        elif isFormatLen2Max64(split_lst):
            gua = int(split_lst[0])
            biangua = int(split_lst[1]) if len(split_lst) == 2 else gua
            coinNumLst, triggerLst = _toCoinsNumLst(gua, biangua)
        else:
            raise ValueError(f'您的输入: {string}, 必须输入一到两个0到63，或者六个0到3的数字 作为硬币数组!')

    return {'gua': gua, 'biangua': biangua, 'coinNumLst': coinNumLst, 'triggerLst': triggerLst}
    # 返回词典，含有主卦变卦序数，coinNum


# 以下为辅助函数

def _toCoinsNumLst(gua_num, bian_gua, Type=int):
    # gua,bian_gua 转 coinsNumLst
    if bian_gua == 64:
        bian_gua = gua_num
    coinNumLst = _get_num_lst_from_pair(gua_num, bian_gua)
    if not coinNumLst:
        raise ValueError(f'您的输入: {gua_num},{bian_gua}, 硬币数组应该至少包含一个数字!')
    triggerLst = [1 if r in [3, 0] else 0 for r in coinNumLst]

    if Type == str:
        return ''.join([str(r) for r in coinNumLst]), triggerLst
    elif Type == int:
        return coinNumLst, triggerLst


def _toGuaNum(coinNumLst: list[int]):
    assert len(coinNumLst) == 6 and all([r in [0, 1, 2, 3] for r in coinNumLst])
    guaLst = [1 if r == 3 else 2 if r == 0 else r for r in coinNumLst]  # 列表 coinsNumber_list 中的每个元素根据其值进行映射
    bianGuaLst = [2 if r == 3 else 1 if r == 0 else r for r in coinNumLst]
    triggerLst = [1 if r in [3, 0] else 0 for r in coinNumLst]
    gua = GuaConverter.to_gua_idx_max2(guaLst)
    if all(r in [1, 2] for r in coinNumLst):
        biangua = gua
    else:
        biangua = GuaConverter.to_gua_idx_max2(bianGuaLst)
    return triggerLst, gua, biangua
